<template>
  <div class="search-div">
    <!-- 搜索表单 -->
    <el-form label-width="70px" size="small">
      <el-form-item label="角色名称">
        <el-input
          style="width: 100%"
          placeholder="角色名称"
          v-model="queryModel.roleName"
        ></el-input>
      </el-form-item>
      <el-row style="display: flex">
        <el-button type="primary" size="small" @click="searchBtn">
          搜索
        </el-button>
        <el-button size="small" @click="resetBtn">重置</el-button>
      </el-row>
    </el-form>

    <!-- 添加按钮 -->
    <div class="tools-div">
      <el-button type="success" size="small" @click="addBtn">添 加</el-button>
    </div>

    <!--- 角色表格数据 -->
    <el-table :data="list" style="width: 100%">
      <el-table-column type="index" width="180" label="序号" />
      <el-table-column prop="roleName" label="角色名称" width="180" />
      <el-table-column prop="roleCode" label="角色code" width="180" />
      <el-table-column prop="createTime" label="创建时间" />
      <el-table-column label="操作" align="center" width="280">
        <template #default="scope">
          <el-button type="primary" size="small" @click="editBtn(scope.row)">
            修改
          </el-button>
          <el-button
            type="warning"
            size="small"
            @click="assignMenuBtn(scope.row)"
          >
            分配菜单
          </el-button>
          <el-button type="danger" size="small" @click="deleteBtn(scope.row)">
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 添加角色表单对话框 -->
    <el-dialog v-model="dialogVisible" :title="title" width="30%">
      <el-form
        label-width="120px"
        :model="roleModel"
        ref="formRef"
        :rules="rules"
      >
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="roleModel.roleName" />
        </el-form-item>
        <el-form-item label="角色Code" prop="roleCode">
          <el-input v-model="roleModel.roleCode" />
        </el-form-item>
        <el-form-item label="描述" prop="description">
          <el-input v-model="roleModel.description" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitBtn">提交</el-button>
          <el-button @click="dialogVisible = false">取消</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
    <!-- 分配角色菜单弹框 -->
    <el-dialog :title="title" v-model="assignRoleDialogVisible" width="30%">
      <el-form label-width="120px">
        <el-tree
          :data="menuTreeList"
          ref="treeRef"
          :show-checkbox="true"
          default-expand-all
          :check-on-click-node="true"
          node-key="id"
          :props="defaultProps"
        />
        <el-form-item>
          <el-button type="primary" @click="doAssign">确定</el-button>
          <el-button @click="assignRoleDialogVisible = false">取消</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
    <!--分页条-->
    <el-pagination
      :page-sizes="[5, 10, 20, 30]"
      layout="total, sizes, prev, pager, next"
      :page-size="queryModel.pageSize"
      :total="total"
      @current-change="handleCurrentChange"
      @size-change="handleSizeChange"
    />
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, nextTick } from 'vue'
import {
  getRoleList,
  addRole,
  editRole,
  deleteRole,
  getAssignedMenuList,
  saveRoleMenu,
} from '@/api/sysRole'
import { ElMessage, ElMessageBox } from 'element-plus'
//添加弹框
const dialogVisible = ref(false)
//角色分配菜单弹框
const assignRoleDialogVisible = ref(false)
const defaultProps = {
  children: 'children',
  label: 'title',
}
//定义角色id
const roleId = ref('')
//弹框标题
const title = ref('')
//开关
const flag = ref('0') //0添加1修改
//定义树节点菜单数据
const menuTreeList = ref([
  {
    id: 1,
    label: 'Level one 1',
    children: [
      {
        id: 4,
        label: 'Level two 1-1',
        children: [
          {
            id: 9,
            label: 'Level three 1-1-1',
          },
          {
            id: 10,
            label: 'Level three 1-1-2',
          },
        ],
      },
    ],
  },
  {
    id: 2,
    label: 'Level one 2',
    children: [
      {
        id: 5,
        label: 'Level two 2-1',
      },
      {
        id: 6,
        label: 'Level two 2-2',
      },
    ],
  },
  {
    id: 3,
    label: 'Level one 3',
    children: [
      {
        id: 7,
        label: 'Level two 3-1',
      },
      {
        id: 8,
        label: 'Level two 3-2',
      },
    ],
  },
])
//定义树借点的对象
const treeRef = ref()
//定义弹框对象
const formRef = ref()
//定义查询参数
const queryModel = reactive({
  pageNum: 1,
  pageSize: 5,
  roleName: '',
})
//定义添加角色参数
const roleModel = reactive({
  id: '',
  roleCode: '', //角色编码
  roleName: '',
  description: '',
})
// 分页条总记录数
let total = ref(0)

// 定义表格数据模型
let list = ref([
  {
    id: 9,
    roleName: '系统管理员',
    roleCode: 'xtgly',
    createTime: '2023-07-31',
  },
  {
    id: 10,
    roleName: '商品管理员',
    roleCode: 'spgly',
    createTime: '2023-07-31',
  },
])
//表单校验
const rules = reactive({
  roleName: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
  roleCode: [{ required: true, message: '请输入角色编码', trigger: 'blur' }],
  description: [{ required: true, message: '请输入角色描述', trigger: 'blur' }],
})
//获取角色按钮
const searchBtn = async () => {
  const res = await getRoleList(queryModel)
  if (res.code === 200 && res) {
    list.value = res.data.list
    total.value = res.data.total
  }
}
//删除角色
const deleteBtn = row => {
  ElMessageBox.confirm('此操作将永久删除该记录, 是否继续?', 'Warning', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(async () => {
    const res = await deleteRole(row.id)
    if (res.code === 200 && res) {
      ElMessage.success(res.message)
      searchBtn()
    } else {
      ElMessage.error(res.message)
    }
  })
}
//分配角色菜单按钮
const assignMenuBtn = async row => {
  assignRoleDialogVisible.value = true
  title.value = '分配角色菜单'
  roleId.value = row.id
  //解构出数据
  const { data } = await getAssignedMenuList(row.id)
  menuTreeList.value = data.menuTreeList
  treeRef.value.setCheckedKeys(data.checkedKeys)
}
//提交角色分配菜单表单

const doAssign = async () => {
  const checkedNodes = treeRef.value.getCheckedNodes() // 获取选中的节点
  const checkedNodesIds = checkedNodes.map(node => {
    // 获取选中的节点的id
    return {
      id: node.id,
      isHalf: 0,
    }
  })

  // 获取半选中的节点数据，当一个节点的子节点被部分选中时，该节点会呈现出半选中的状态
  const halfCheckedNodes = treeRef.value.getHalfCheckedNodes()
  const halfCheckedNodesIds = halfCheckedNodes.map(node => {
    // 获取半选中节点的id
    return {
      id: node.id,
      isHalf: 1,
    }
  })

  // 将选中的节点id和半选中的节点的id进行合并
  const menuIds = [...checkedNodesIds, ...halfCheckedNodesIds]
  console.log(menuIds)

  // 构建请求数据
  const assignMenuDto = {
    roleId: roleId.value,
    menuIdList: menuIds,
  }

  // 发送请求
  await saveRoleMenu(assignMenuDto)
  ElMessage.success('操作成功')
  assignRoleDialogVisible.value = false
}
//提交表单
const submitBtn = async () => {
  // 先进行表单校验
  if (!formRef.value) {
    ElMessage.warning('表单未初始化')
    return
  }

  try {
    // 执行表单验证
    const isValid = await formRef.value.validate()
    if (!isValid) {
      ElMessage.warning('请检查表单填写是否正确')
      return
    }

    let res = null
    if (flag.value === '0') {
      // 添加角色
      res = await addRole(roleModel)
    } else {
      // 编辑角色
      res = await editRole(roleModel)
    }

    if (res.code === 200 && res) {
      ElMessage.success(res.message)
      dialogVisible.value = false
      searchBtn()
    } else {
      ElMessage.error(res.message || '操作失败')
    }
  } catch (error) {
    ElMessage.error('表单校验失败或网络错误')
  }
}

//清空搜索按钮
const resetBtn = () => {
  queryModel.roleName = ''
  searchBtn()
}
const editBtn = async row => {
  dialogVisible.value = true
  title.value = '编辑角色'
  flag.value = '1'
  Object.assign(roleModel, row)
}
//当前页面改变时触发
const handleCurrentChange = pageNum => {
  queryModel.pageNum = pageNum
  searchBtn()
}
//每页条数改变时触发
const handleSizeChange = pageSize => {
  queryModel.pageSize = pageSize
  searchBtn()
}

//点击添加按钮
const addBtn = () => {
  flag.value = '0'
  title.value = '添加角色'
  Object.assign(roleModel, {
    id: '',
    roleCode: '', //角色编码
    roleName: '',
    description: '',
  })
  // 再打开对话框
  dialogVisible.value = true
}
onMounted(() => {
  searchBtn()
})
</script>

<style scoped>
.search-div {
  margin-bottom: 10px;
  padding: 10px;
  border: 1px solid #ebeef5;
  border-radius: 3px;
  background-color: #fff;
}

.tools-div {
  margin: 10px 0;
  padding: 10px;
  border: 1px solid #ebeef5;
  border-radius: 3px;
  background-color: #fff;
}
</style>